package com.example.project3.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.*;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.project3.entity.User;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName MyJWT .java
 * @Description empty
 * @Author LiuJinyu
 * @Date 2023/5/31 9:20
 * @Version 1.0
 */
@Component
public class MyJWT {
    private static final String SECRET = "A)A#@BS#D!@#DDF^%A";
    /**
     * 过期时间，单位 2天
     */
    private final Integer exTime = 2;

    public String create(Map<String, Object> map) {
        Instant expires = Instant.from(ZonedDateTime.now().plusDays(exTime));
        return JWT.create()
                .withPayload(map)
                .withExpiresAt(expires)
                .sign(Algorithm.HMAC256(SECRET));
    }

    public String create(User user) {
        Map<String, Object> map = new HashMap<>();
        map.put("uid", user.getUid());
        map.put("nickname", user.getNickname());
        Instant expires = Instant.from(ZonedDateTime.now().plusDays(exTime));
        return JWT.create()
                .withPayload(map)
                .withExpiresAt(expires)
                .sign(Algorithm.HMAC256(SECRET));
    }

    /**
     * 验证token
     *
     * @param token token
     */
    public void verify(String token) {
        JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
    }

    /**
     * 验证并获取一个值
     *
     * @param token
     * @param key
     * @return
     * @throws JWTDecodeException
     * @throws SignatureVerificationException
     * @throws TokenExpiredException
     * @throws AlgorithmMismatchException
     * @throws InvalidClaimException
     */
    public Object verifyAndGet(String token, String key) throws JWTDecodeException, SignatureVerificationException, TokenExpiredException, AlgorithmMismatchException, InvalidClaimException {
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT verify2 = jwtVerifier.verify(token);
        return verify2.getClaim(key);
    }

    /**
     * 从HttpServletRequest中取出token，并从token中获取一个值。
     *
     * @param httpServletRequest
     * @param key
     * @return
     * @throws JWTDecodeException
     * @throws SignatureVerificationException
     * @throws TokenExpiredException
     * @throws AlgorithmMismatchException
     * @throws InvalidClaimException
     */
    public Object verifyAndGet(HttpServletRequest httpServletRequest, String key) throws JWTDecodeException, SignatureVerificationException, TokenExpiredException, AlgorithmMismatchException, InvalidClaimException {
        String token = httpServletRequest.getHeader("token");
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT verify2 = jwtVerifier.verify(token);
        return verify2.getClaim(key);
    }

    /**
     * 从HttpServletRequest的token中快速取出用户uid
     *
     * @param request
     * @return
     */
    public Integer getUid(HttpServletRequest request) {
        String token = request.getHeader("token");
        Map<String, Claim> userInfo = this.getUserInfo(token);
        return userInfo.get("uid").asInt();
    }

    public Map<String, Claim> getUserInfo(String token) {
        return JWT.decode(token).getClaims();
    }
}
